package org.x.note.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/**
 * [文件名称]<br>
 * FileUtil <br>
 * <br>
 * [文件描述]<br>
 * 文件操作工具类<br>
 * <br>
 * [修改记录]<br>
 * 2012-6-14 ver1.00 创建 xyl<br>
 * 
 * @author xyl
 * @version 1.00
 */
public class FileUtil {

	/**
	 * 创建文件
	 * 
	 * @param filePath
	 * @throws IOException
	 */
	public static void creatFile(String filePath) throws IOException {
		File file = new File(filePath);
		if (!file.exists()) {
			file.createNewFile();
		}
	}

	/**
	 * 删除文件或文件夹
	 * 
	 * @param filePath
	 *            文件路径
	 * @return
	 * @throws FileNotFoundException
	 */
	public static void delFile(String filePath) throws FileNotFoundException {
		File file = new File(filePath);

		if (!file.exists()) {
			throw new FileNotFoundException(filePath + "不存在");
		}

		delFile(file);
	}

	private static void delFile(File file) {
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			for (int i = 0; i < files.length; i++) {
				// 删除子文件夹
				delFile(files[i]);
			}
		}
		file.delete();
	}

	/**
	 * 拷贝文件或文件夹
	 * 
	 * @param source
	 *            源路径
	 * @param target
	 *            目标路径
	 * @throws IOException
	 */
	public static void copyFile(String source, String target)
			throws IOException {
		File sou = new File(source);
		if (!sou.exists()) {
			throw new FileNotFoundException(source + "不存在");
		}

		File tar = new File(target);
		if (!tar.exists()) {
			throw new FileNotFoundException(target + "不存在");
		}

		copyFile(sou, tar);
	}

	private static void copyFile(File source, File target) throws IOException {
		File tar = new File(target.getAbsolutePath() + File.separator
				+ source.getName());

		if (source.isDirectory()) {
			File[] files = source.listFiles();
			tar.mkdir();
			for (int i = 0; i < files.length; i++) {
				copyFile(files[i], tar);
			}
		} else if (source.isFile()) {
			FileInputStream input = null;
			FileOutputStream output = null;
			try {
				input = new FileInputStream(source);
				output = new FileOutputStream(tar);
				byte[] buf = new byte[512];
				int len = 0;
				// “-1”文件末尾的标志
				while ((len = input.read(buf)) != -1) {
					output.write(buf, 0, len);

				}
			} finally {
				input.close();
				output.close();
			}
		}
	}

	/**
	 * 剪切文件或文件夹
	 * 
	 * @param source
	 *            源路径
	 * @param target
	 *            目标路径
	 * @throws IOException
	 */
	public static void cutFile(String source, String target) throws IOException {
		copyFile(source, target);
		delFile(source);
	}

	/**
	 * ZIP压缩
	 * 
	 * @param source
	 *            源路径
	 * @param target
	 *            目标路径
	 * @throws IOException
	 */
	public static void toZip(String source, String target) throws IOException {
		File sou = new File(source);
		if (!sou.exists()) {
			throw new FileNotFoundException(source + "不存在");
		}

		File tar = new File(target);
		if (!tar.exists()) {
			throw new FileNotFoundException(target + "不存在");
		}

		FileOutputStream output = null;
		ZipOutputStream zos = null;
		try {
			output = new FileOutputStream(target + ".zip");
			zos = new ZipOutputStream(output);
			zipFile(zos, source);

		} finally {
			zos.close();
			output.close();
		}

	}

	private static void zipFile(ZipOutputStream zos, String source)
			throws IOException {
		File file = new File(source);

		if (file.isFile()) {
			zipFile(zos, file);
		} else {
			File[] files = file.listFiles();
			for (int i = 0; i < files.length; i++) {
				if (files[i].isFile()) {
					zipFile(zos, files[i]);
				}
				if (!(files[i].exists())) {
					zos.putNextEntry(new ZipEntry(files[i].getAbsolutePath()));
				}
				if (files[i].isDirectory()) {// 如果是子文件夹
					zipFile(zos, files[i].getAbsolutePath());
				}
			}
		}
	}

	private static void zipFile(ZipOutputStream zos, File file)
			throws IOException {
		FileInputStream input = null;
		try {
			input = new FileInputStream(file);
			String filePath = file.getAbsolutePath();
			zos.putNextEntry(new ZipEntry(filePath.substring(filePath
					.indexOf("\\") + 1)));
			byte[] b = new byte[1024 * 5];
			int len = 0;
			while ((len = input.read(b)) != -1) {
				zos.write(b, 0, len);
			}
		} finally {
			input.close();
		}
	}

	/**
	 * ZIP解压缩
	 * 
	 * @param source
	 *            源路径
	 * @param target
	 *            目标路径
	 * @throws IOException
	 */
	public static void unZipFile(String source, String target)
			throws IOException {
		InputStream is = null;
		FileOutputStream fos = null;
		try {
			ZipFile zFile = new ZipFile(source);
			Enumeration<?> emu = zFile.entries();
			while (emu.hasMoreElements()) {
				ZipEntry entry = (ZipEntry) emu.nextElement();
				// 会把目录作为一个file读出一次，所以只建立目录就可以，之下的文件还会被迭代到
				if (entry.isDirectory()) {
					new File(target + entry.getName()).mkdirs();
				}
				is = zFile.getInputStream(entry);
				File file = new File(target + entry.getName());
				/*
				 * 加入这个的原因是zipfile读取文件是随机读取的，这就造成可能先读取一个文件
				 * 而这个文件所在的目录还没有出现过，所以要建出目录来。
				 */
				File parent = file.getParentFile();
				if (parent != null && (!parent.exists())) {
					parent.mkdirs();
				}
				fos = new FileOutputStream(file);
				byte[] buf = new byte[1024];
				int len = 0;
				while ((len = is.read(buf)) != -1) {
					fos.write(buf, 0, len);
				}
			}
		} finally {
			if (fos != null) {
				fos.flush();
				fos.close();
			}
			if (is != null) {
				is.close();
			}
		}
	}
}
